#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**
 * 霍纳多项式结构体（模拟 Python 类）
 * 成员：
 *   coeffs: 多项式系数数组（按最高次到最低次排列，如 3x²+2x+1 存储为 [3,2,1]）
 *   len: 系数数组长度
 *   eval: 函数指针，模拟 __call__ 方法，实现多项式求值
 */
typedef struct {
    double *coeffs;
    int len;
    double (*eval)(const struct HornerPolynomial*, double);
} HornerPolynomial;

/**
 * 多项式求值函数（霍纳法则），对应 Python 的 __call__ 方法
 * @param poly: 多项式结构体指针
 * @param x: 自变量值
 * @return: 多项式在 x 处的值
 */
static double horner_evaluate(const HornerPolynomial *poly, double x) {
    if (poly == NULL || poly->coeffs == NULL || poly->len == 0) {
        fprintf(stderr, "Invalid polynomial\n");
        return 0.0;
    }

    double result = 0.0;
    // 霍纳法则核心逻辑：result = result * x + coeff
    for (int i = 0; i < poly->len; i++) {
        result = result * x + poly->coeffs[i];
    }
    return result;
}

/**
 * 创建霍纳多项式实例（模拟 Python 的 __init__ 方法）
 * @param coeffs: 系数数组（输入）
 * @param len: 系数数组长度
 * @return: 多项式结构体指针（成功），NULL（失败）
 */
HornerPolynomial* horner_polynomial_create(const double *coeffs, int len) {
    if (coeffs == NULL || len <= 0) {
        fprintf(stderr, "Invalid coefficients\n");
        return NULL;
    }

    // 分配结构体内存
    HornerPolynomial *poly = (HornerPolynomial*)malloc(sizeof(HornerPolynomial));
    if (poly == NULL) {
        fprintf(stderr, "Memory allocation failed for polynomial struct\n");
        return NULL;
    }

    // 分配系数数组内存并拷贝数据
    poly->coeffs = (double*)malloc(len * sizeof(double));
    if (poly->coeffs == NULL) {
        fprintf(stderr, "Memory allocation failed for coefficients\n");
        free(poly);
        return NULL;
    }
    memcpy(poly->coeffs, coeffs, len * sizeof(double));
    poly->len = len;
    poly->eval = horner_evaluate;  // 绑定求值函数

    return poly;
}

/**
 * 销毁霍纳多项式实例（释放内存）
 * @param poly: 多项式结构体指针
 */
void horner_polynomial_destroy(HornerPolynomial *poly) {
    if (poly != NULL) {
        free(poly->coeffs);  // 释放系数数组
        free(poly);         // 释放结构体
    }
}

/**
 * 获取多项式系数（模拟 Python 的 @property 装饰器）
 * @param poly: 多项式结构体指针
 * @param out_coeffs: 输出系数数组（需提前分配内存，长度 >= poly->len）
 * @param out_len: 输出系数数组长度
 * @return: 0 成功，-1 失败
 */
int horner_polynomial_get_coeffs(const HornerPolynomial *poly, double *out_coeffs, int *out_len) {
    if (poly == NULL || out_coeffs == NULL || out_len == NULL) {
        return -1;
    }
    memcpy(out_coeffs, poly->coeffs, poly->len * sizeof(double));
    *out_len = poly->len;
    return 0;
}

// 示例测试代码
int main() {
    // 示例：多项式 3x² + 2x + 1，系数按最高次到最低次排列 [3, 2, 1]
    double coeffs[] = {3.0, 2.0, 1.0};
    int len = sizeof(coeffs) / sizeof(coeffs[0]);

    // 创建多项式实例
    HornerPolynomial *poly = horner_polynomial_create(coeffs, len);
    if (poly == NULL) {
        return -1;
    }

    // 1. 调用求值方法（模拟 Python 的 poly(x)）
    double x = 2.0;
    double value = poly->eval(poly, x);
    printf("多项式在 x=%.1f 处的值：%.1f\n", x, value);  // 预期：3*(2)^2 + 2*2 +1 = 17.0

    // 2. 获取多项式系数（模拟 Python 的 poly.polynomial）
    double *coeffs_copy = (double*)malloc(len * sizeof(double));
    int coeffs_len;
    if (horner_polynomial_get_coeffs(poly, coeffs_copy, &coeffs_len) == 0) {
        printf("多项式系数：");
        for (int i = 0; i < coeffs_len; i++) {
            printf("%.1f ", coeffs_copy[i]);
        }
        printf("\n");
    }
    free(coeffs_copy);

    // 3. 销毁实例，释放内存
    horner_polynomial_destroy(poly);

    return 0;
}